/**
 * Copyright 2012 Ricardo Engel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mookt.dcubed.mongodb;

import java.io.Serializable;

import org.mookt.dcubed.AggregateRoot;
import org.mookt.dcubed.Repository;

import com.google.gson.Gson;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

/**
 * @author Ricardo Engel
 */
public class MongoRepository<T extends AggregateRoot<ID>, ID extends Serializable>
		implements Repository<T, ID> {

	private static final String ID_NAME = "_id";

	private static Gson GSON = new Gson();

	private DBCollection collection;

	private Class<T> type;

	public MongoRepository(DB db, Class<T> type) {
		this.collection = db.getCollection(type.getSimpleName());
		this.type = type;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mookt.dcubed.Repository#save(org.mookt.dcubed.AggregateRoot)
	 */
	public void save(T entity) {
		DBObject doc = (DBObject) JSON.parse(GSON.toJson(entity));
		doc.put(ID_NAME, entity.getId());
		collection.insert(doc);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mookt.dcubed.Repository#find(java.io.Serializable)
	 */
	public T find(ID id) {
		BasicDBObject query = new BasicDBObject(ID_NAME, id);
		DBObject result = collection.findOne(query);
		return GSON.fromJson(JSON.serialize(result), type);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mookt.dcubed.Repository#exists(java.io.Serializable)
	 */
	public boolean exists(ID id) {
		return collection.count(new BasicDBObject(ID_NAME, id)) > 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mookt.dcubed.Repository#count()
	 */
	public long count() {
		return collection.count();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mookt.dcubed.Repository#delete(java.io.Serializable)
	 */
	public void delete(ID id) {
		collection.remove(new BasicDBObject(ID_NAME, id));
	}

}